"""

@Time: 2021/2/5 23:06
@Author:
@File: base_scanner.py
"""
import os
from fastapi import UploadFile
from typing import List, Tuple
import aiofiles

from exceptions import ScannerSaveException, ScannerReadException
from models.dto.mark_dto.file_upload_dto import UploadResult
from models.normal import BaseCollectedCardDataModel


class CardScannerBase:
    def __init__(self):
        pass

    async def extract_data(self, card_file: UploadFile) -> BaseCollectedCardDataModel:
        pass

    async def save(self, card_file: UploadFile, dir_path: str) -> None:
        try:
            contents = await card_file.read()  # 读取文件内容
            file_path = os.path.join(dir_path, card_file.filename)
            # 将临时文件中的数据写入真实文件中
            async with aiofiles.open(file_path, mode='wb') as f:
                await f.write(contents)
        except Exception as e:
            raise ScannerSaveException(str(e))

    async def save_and_extract_all_files(self, card_files: List[UploadFile], dir_name) -> Tuple[List, UploadResult]:
        """
        对每一个上传的文件进行保存和提取数据的操作
        :param card_files: 上传的所有文件
        :param dir_name: 保存文件时所在的路径
        :return: 提取数据后的数据列表、读取与保存结果
        """
        success_read_files: List[str] = []
        fail_read_files: List[str] = []
        success_save_files: List[str] = []
        fail_save_files: List[str] = []
        card_data_list = []  # 卡片读取后的数据列表

        for f in card_files:
            # 读取文件中数据
            try:
                read_result = await self.extract_data(f)
                card_data_list.append(read_result)
                success_read_files.append(f.filename)
            except ScannerReadException:
                fail_read_files.append(f.filename)
            # 保存文件
            try:
                await self.save(f, dir_name)
                success_save_files.append(f.filename)
            except ScannerSaveException:
                fail_save_files.append(f.filename)

        return card_data_list, UploadResult(
            success_read_files=success_read_files,
            success_save_files=success_save_files,
            fail_read_files=fail_read_files,
            fail_save_files=fail_save_files
        )
